package com.darren.archive.service.impl;

import com.darren.archive.component.SysParameterHelper;
import com.darren.archive.dao.SysUserDao;
import com.darren.archive.entity.SysUser;
import com.darren.archive.repository.SysUserRepository;
import com.darren.archive.service.SysUserService;
import com.darren.framework.Exception.ArchiveException;
import com.darren.framework.service.impl.GenericServiceImpl;
import com.darren.framework.utils.Constant;
import com.darren.framework.utils.EncryptAESUtil;
import com.darren.framework.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * <pre>
 * *********************************************
 * Copyright DARREN
 * All rights reserved.
 * Description: TODO(description)
 * HISTORY:
 * *********************************************
 *  Version		Date		Author	   		Desc
 *   v1.0       2018-04-11  Darren Zhou    Create
 *
 * *********************************************
 * </pre>
 */

@Service
@Transactional(rollbackFor = Exception.class)//默认该类的所有方法都开启事务，遇到Exception就回滚
public class SysUserServiceImpl extends GenericServiceImpl<SysUser, Long> implements SysUserService {

    @Resource
    private SysUserDao sysUserDao;


    @Autowired
    private SysUserRepository sysUserRepository;

    @Override
    @Cacheable(value = Constant.CACHE_SYS_USERS, key = "#queryString")
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, readOnly = true)
    public SysUser findByUserAccountOrMobile(String queryString) {
        logger.info("login validate...");
        return sysUserDao.findByUserAccountOrMobile(queryString);
    }

    @Override
    @Cacheable(value = Constant.CACHE_SYS_USERS, key = "#name")
    public List<SysUser> findByNameLike(String name) {
        return sysUserRepository.findByNameLikeAndEditable(name,true);
    }

    @Override
    @Cacheable(value = Constant.CACHE_SYS_USERS, key = "#name")
    public Page<SysUser> findByNameLike(String name, Pageable pageable) {
        return sysUserRepository.findByNameLikeAndEditable(name,true,pageable);
    }

    @Override
    @Cacheable(value = Constant.CACHE_SYS_USERS)
    public Page<SysUser> findAll(Pageable pageable) {
        return sysUserRepository.findByEditable(true,pageable);
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_USERS, allEntries = true)
    public SysUser saveEnable(SysUser record) {
        SysUser sysUser = sysUserDao.findById(record.getId());
        sysUser.setEnable(record.isEnable());
        return sysUserDao.save(sysUser);
    }

    /**
     * 修改用户密码
     *
     * @param id          用户id
     * @param oldPassword 旧密码
     * @param password    新密码
     * @return
     */
    @CacheEvict(value = Constant.CACHE_SYS_USERS, allEntries = true)
    @Override
    public Integer updatePassword(Long id, String oldPassword, String password) {
        if(StringUtils.isEmpty(password)){
            throw new ArithmeticException("新密码不能为空。");
        }
        if(StringUtils.isEmpty(oldPassword)){
            throw new ArithmeticException("旧密码不能为空。");
        }
        SysUser sysUser = sysUserDao.findById(id);
        if(sysUser == null){
            throw new ArithmeticException("用户id无效。");
        }
        if(StringUtils.isEmpty(sysUser.getPassword())
            || sysUser.getPassword().equals(EncryptAESUtil.getEncryption(oldPassword, SysParameterHelper.getEncryptKey()))){
            return sysUserRepository.updatePassword(id,EncryptAESUtil.getEncryption(password,SysParameterHelper.getEncryptKey()));
        }
        throw new ArithmeticException("修改密码失败。");
    }

    /**
     * 根据用户 id 重置用户密码
     *
     * @param id 用户id
     * @return
     */
    @Override
    @CacheEvict(value = Constant.CACHE_SYS_USERS, allEntries = true)
    public Integer resetPassword(Long id) {
        return sysUserRepository.updatePassword(id,EncryptAESUtil.getEncryption(Constant.DEFAULT_PASSWORD,SysParameterHelper.getEncryptKey()));
    }

    @Override
    @Caching(evict = {@CacheEvict(value = Constant.CACHE_SYS_USERS, allEntries = true),
            @CacheEvict(value = Constant.CACHE_SYS_USERS, key = "#entity.mobile"),
            @CacheEvict(value = Constant.CACHE_SYS_USERS, key = "#entity.id")})
    public SysUser save(SysUser entity) {
        if(entity == null){
            throw new ArchiveException("没获取到要保存的用户信息。");
        }else if(entity.getUserAccount() == null){
            throw new ArchiveException("用户帐号不能为空。");
        }else{
            SysUser dbUser = sysUserDao.findByUserAccountOrMobile(entity.getUserAccount());
            if(dbUser != null && dbUser.getId() != entity.getId()){
                throw new ArchiveException(String.format("用户帐号【%s】已存在。",dbUser.getUserAccount()));
            }
        }
        if(entity.getId() == null){
            entity.setPassword(EncryptAESUtil.getEncryption(Constant.DEFAULT_PASSWORD,SysParameterHelper.getEncryptKey()));
            entity = sysUserDao.save(entity);
        }else {
            entity = sysUserDao.update(entity);
        }
        return entity;
    }

    @Override
    @Cacheable(value = Constant.CACHE_SYS_USERS, key = "#id")
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, readOnly = true)
    public SysUser findById(Long id) {
        return sysUserDao.findById(id);
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_USERS, allEntries = true)
    public void delete(SysUser entity) {
        sysUserDao.delete(entity);
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_USERS, allEntries = true)
    public void deleteById(Long id) {
        sysUserDao.deleteById(id);
    }


}
